/**
 * *****************************************************************************
 * Copyright 2011 See AUTHORS file.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 * ****************************************************************************
 */
package sg.atom.utils.io;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;

@Deprecated
/**
 * Extends {@link DataInputStream} with additional convenience methods.
 *
 * Use Google ByteArray instead
 *
 * @author Nathan Sweet
 */
public class DataInput extends DataInputStream {

    private char[] chars = new char[32];

    public DataInput(InputStream in) {
        super(in);
    }

    /**
     * Reads a 1-5 byte int.
     */
    public int readInt(boolean optimizePositive) throws IOException {
        int b = read();
        int result = b & 0x7F;
        if ((b & 0x80) != 0) {
            b = read();
            result |= (b & 0x7F) << 7;
            if ((b & 0x80) != 0) {
                b = read();
                result |= (b & 0x7F) << 14;
                if ((b & 0x80) != 0) {
                    b = read();
                    result |= (b & 0x7F) << 21;
                    if ((b & 0x80) != 0) {
                        b = read();
                        result |= (b & 0x7F) << 28;
                    }
                }
            }
        }
        return optimizePositive ? result : ((result >>> 1) ^ -(result & 1));
    }

    /**
     * Reads the length and string of UTF8 characters, or null.
     *
     * @return May be null.
     */
    public String readString() throws IOException {
        int charCount = readInt(true);
        switch (charCount) {
            case 0:
                return null;
            case 1:
                return "";
        }
        charCount--;
        if (chars.length < charCount) {
            chars = new char[charCount];
        }
        char[] chars = this.chars;
        // Try to read 7 bit ASCII chars.
        int charIndex = 0;
        int b = 0;
        while (charIndex < charCount) {
            b = read();
            if (b > 127) {
                break;
            }
            chars[charIndex++] = (char) b;
        }
        // If a char was not ASCII, finish with slow path.
        if (charIndex < charCount) {
            readUtf8_slow(charCount, charIndex, b);
        }
        return new String(chars, 0, charCount);
    }

    private void readUtf8_slow(int charCount, int charIndex, int b) throws IOException {
        char[] chars = this.chars;
        while (true) {
            switch (b >> 4) {
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                    chars[charIndex] = (char) b;
                    break;
                case 12:
                case 13:
                    chars[charIndex] = (char) ((b & 0x1F) << 6 | read() & 0x3F);
                    break;
                case 14:
                    chars[charIndex] = (char) ((b & 0x0F) << 12 | (read() & 0x3F) << 6 | read() & 0x3F);
                    break;
            }
            if (++charIndex >= charCount) {
                break;
            }
            b = read() & 0xFF;
        }
    }
}